package com.micolor.logr.runtime.component;

import com.micolor.logr.runtime.entity.StorageData;
import com.micolor.logr.runtime.interfaces.LogDataPersistenceInterface;
import com.micolor.logr.runtime.properties.LogREnumsProperties;
import com.micolor.logr.runtime.util.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author EvanGe
 * @Type StorageClassInvokeComponent.java
 * @Desc
 * @date 2024/7/17 14:51
 */
@Component
@Slf4j
public class StorageClassInvokeComponent {

    @Autowired
    private LogREnumsProperties logREnumsProperties;

    /**
     * 根据反射类的名称执行反射类的getLogFieldEnum方法，并返回结果
     *
     * @param className 反射类的名称
     * @throws ClassNotFoundException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws RuntimeException
     */
    public void saveLogData(String className, StorageData storageData) throws
            ClassNotFoundException,
            NoSuchMethodException,
            InvocationTargetException,
            IllegalAccessException,
            RuntimeException {

        //类的反射和获取
        Class<?> clazz = Class.forName(className);
        String simpleName = clazz.getSimpleName();
        String firstLowerName = simpleName.substring(0,1).toLowerCase() + simpleName.substring(1);
        Object o = SpringContextUtil.getBean(firstLowerName, clazz);
        //判断类是否继承了 LogDataPersistenceInterface
        boolean isImplement = false;
        for (Class<?> i : clazz.getInterfaces()) {
            if (i == LogDataPersistenceInterface.class) {
                isImplement = true;
                break;
            }
        }

        if (isImplement) {
            //方法反射
            Method getLogFieldEnum = clazz.getMethod("saveLogData",StorageData.class);
            getLogFieldEnum.setAccessible(true);
            //执行反射类的反射方法
            getLogFieldEnum.invoke(o,storageData);
        } else {
            throw new RuntimeException("配置文件中logr.storage.initCls配置项指定的类必须实现com.micolor.annotationdemo.log.interfaces.LogDataPersistenceInterface接口");
        }
    }
}
